package com.inifitness.tenant.core.config.mp.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;

/**
 * List类型转换类
 *
 * @author sunjinfeng
 * @version 1.0.0
 * @since 2024-01-10 13:32
 */
@Log4j2
@MappedJdbcTypes(JdbcType.VARCHAR)  //数据库类型
@MappedTypes({List.class})          //java数据类型
public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType)
      throws SQLException {
    String content = Objects.isNull(parameter) ? null : JSONUtil.toJsonStr(parameter);
    ps.setString(i, content);
  }

  @Override
  public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return this.getListByJsonArrayString(rs.getString(columnName));
  }

  @Override
  public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return this.getListByJsonArrayString(rs.getString(columnIndex));
  }

  @Override
  public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return this.getListByJsonArrayString(cs.getString(columnIndex));
  }

  private List<T> getListByJsonArrayString(String content) {
    return StringUtils.hasLength(content) ? JSONUtil.toBean(content, this.specificType(), true)
        : new ArrayList<>();
  }

  /**
   * 具体类型，由子类提供
   *
   * @return 具体类型
   */
  protected abstract TypeReference<List<T>> specificType();
}
